﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using NLog;

namespace XmlServer.Hosting.Service.Helpers
{
    public class Settings
    {

        public Settings()
        {
            LoadSettings();
        }

        public string ProcessorIpAddress { get; set; }
        public int ProcessingPort { get; set; }
        public int NumberOfProcessorThreads { get; set; }
        public string ProcessingOperatorsFolder { get; set; }

        public string PriorityIpAddress { get; set; }
        public int PriorityPort { get; set; }        
        public int NumberOfPriorityThreads { get; set; }        
        public string PriorityOperatorsFolder { get; set; }

        public bool LogDebugMessage { get; set; }
        public bool LogException { get; set; }
        public bool LogPaused { get; set; }
        public bool LogRequestCompleted { get; set; }
        public bool LogRequestServicing { get; set; }
        public bool LogRequestStarted { get; set; }
        public bool LogResumed { get; set; }
        public bool LogStarted { get; set; }
        public bool LogStopped { get; set; }



        public void ValidateSettings()
        {
            if (String.IsNullOrEmpty(ProcessorIpAddress))
                throw new ArgumentNullException("The ProcessorIpAddress cannot be null or empty");

            if (String.IsNullOrEmpty(PriorityIpAddress))
                throw new ArgumentNullException("The PriorityIpAddress cannot be null or empty");

            if (ProcessingPort <= 0)
                throw new ArgumentOutOfRangeException("The ProcessingPort must be greater than zero.");

            if (PriorityPort <= 0)
                throw new ArgumentOutOfRangeException("The PriorityPort must be greater than zero.");

            if (PriorityPort == ProcessingPort)
                throw new ArgumentException("The ProcessingPort and PriorityPort cannot be equal.");

            if (NumberOfProcessorThreads <= 0)
                throw new ArgumentOutOfRangeException("The NumberOfProcessorThreads must be greater than zero.");

            if (NumberOfPriorityThreads <= 0)
                throw new ArgumentOutOfRangeException("The NumberOfPriorityThreads must be greater than zero.");


            if (String.IsNullOrEmpty(ProcessingOperatorsFolder))
                throw new ArgumentNullException("The ProcessingOperatorsFolder cannot be null or empty");

            if (String.IsNullOrEmpty(PriorityOperatorsFolder))
                throw new ArgumentNullException("The PriorityOperatorsFolder cannot be null or empty");

            if (!Directory.Exists(ProcessingOperatorsFolder))
                throw new ArgumentException(String.Format("The ProcessingOperatorsFolder '{0}' does not exist", ProcessingOperatorsFolder));

            if (!Directory.Exists(PriorityOperatorsFolder))
                throw new ArgumentException(String.Format("The PriorityOperatorsFolder '{0}' does not exist", PriorityOperatorsFolder));

        }

        private void LoadSettings()
        {
            this.ProcessorIpAddress = Common.GetAppSetting<string>("ProcessorIpAddress");
            if (String.IsNullOrEmpty(this.ProcessorIpAddress)) this.ProcessorIpAddress = XmlServer.Helper.Utilities.GetLocalIpAddress();

            this.PriorityIpAddress = Common.GetAppSetting<string>("PriorityIpAddress");
            if (String.IsNullOrEmpty(this.PriorityIpAddress)) this.PriorityIpAddress = this.ProcessorIpAddress;

            ProcessingPort = Common.GetAppSetting<int>("ProcessingPort");
            PriorityPort = Common.GetAppSetting<int>("PriorityPort");
            NumberOfProcessorThreads = Common.GetAppSetting<int>("NumberOfProcessorThreads");
            NumberOfPriorityThreads = Common.GetAppSetting<int>("NumberOfPriorityThreads");

            this.ProcessingOperatorsFolder = Common.GetAppSetting<string>("ProcessingOperatorsFolder");
            this.PriorityOperatorsFolder = Common.GetAppSetting<string>("PriorityOperatorsFolder");            

            var logging =  Common.GetAppSetting<string>("LoggingEvents");            
            if (logging.Equals("All", StringComparison.InvariantCultureIgnoreCase))
            {
                this.LogDebugMessage = true;
                this.LogException = true;
                this.LogPaused = true;
                this.LogRequestCompleted = true;
                this.LogRequestServicing = true;
                this.LogRequestStarted = true;
                this.LogResumed = true;
                this.LogStarted = true;
                this.LogStopped = true;                
            }
            else
            {
                if (!String.IsNullOrEmpty(logging))
                {
                    var arrItems = logging.Split(',');
                    foreach (var item in arrItems)
                    {
                        if (String.IsNullOrEmpty(item)) continue;
                        switch (item.Trim().ToLower())
                        {
                            case "debugmessage":
                                this.LogDebugMessage = true;
                                break;

                            case "exception":
                                this.LogException = true;
                                break;

                            case "paused":
                                this.LogPaused = true;
                                break;

                            case "requestcompleted":
                                this.LogRequestCompleted = true;
                                break;

                            case "requestservicing":
                                this.LogRequestServicing = true;
                                break;

                            case "requeststarted":
                                this.LogRequestStarted = true;
                                break;

                            case "resumed":
                                this.LogResumed = true; 
                                break;

                            case "started":
                                this.LogStarted = true;
                                break;

                            case "stopped":
                                this.LogStarted = true;
                                break;
                        }
                    }
                }
            }

        }

        public void LogSettings(Logger logger)
        {
            logger.Info(String.Format("{0} = {1}", "ProcessorIpAddress", ProcessorIpAddress));
            logger.Info(String.Format("{0} = {1}", "ProcessingPort", ProcessingPort));
            logger.Info(String.Format("{0} = {1}", "NumberOfProcessorThreads", NumberOfProcessorThreads));
            logger.Info(String.Format("{0} = {1}", "ProcessingOperatorsFolder", ProcessingOperatorsFolder));


            logger.Info(String.Format("{0} = {1}", "PriorityIpAddress", PriorityIpAddress));
            logger.Info(String.Format("{0} = {1}", "PriorityPort", PriorityPort));
            logger.Info(String.Format("{0} = {1}", "NumberOfPriorityThreads", NumberOfPriorityThreads));
            logger.Info(String.Format("{0} = {1}", "PriorityOperatorsFolder", PriorityOperatorsFolder));

        }

        public string AllLogging
        {
            get 
            { 
                return "DebugMessage, Exception, Paused, RequestCompleted, RequestServicing, RequestStarted, Resumed, Started, Stopped";  
            }
        }

    }
}
